<!DOCTYPE html>
<head>
<meta charset="utf-8">
  <meta name="author" content="JJ Allaire and Yihui Xie" />
  <title>New Tools for Reproducible Research with R</title>
  <style type="text/css">
table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode {
  margin: 0; padding: 0; vertical-align: baseline; border: none; }
table.sourceCode { width: 100%; }
td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; }
td.sourceCode { padding-left: 5px; }
code > span.kw { color: #007020; font-weight: bold; }
code > span.dt { color: #902000; }
code > span.dv { color: #40a070; }
code > span.bn { color: #40a070; }
code > span.fl { color: #40a070; }
code > span.ch { color: #4070a0; }
code > span.st { color: #4070a0; }
code > span.co { color: #60a0b0; font-style: italic; }
code > span.ot { color: #007020; }
code > span.al { color: #ff0000; font-weight: bold; }
code > span.fu { color: #06287e; }
code > span.er { color: #ff0000; font-weight: bold; }
  </style>
<link href='http://fonts.googleapis.com/css?family=Oswald' rel='stylesheet'>
<style>
  html { background-color: black; }
  body { background-color: white; border-radius: 12px}
  /* A section is a slide. It's size is 800x600, and this will never change */
  section {
      font-family: 'Oswald', arial, serif;
      font-size: 20pt;
    }
  address, blockquote, dl, fieldset, form, h1, h2, h3, h4, h5, h6, hr, ol, p, pre, table, ul, dl { padding: 10px 20px 10px 20px; }
  h1, h2, h3 {
    text-align: center;
    margin: 10pt 10pt 20pt 10pt;
  }
  ul, ol {
    margin: 10px 10px 10px 50px;
  }
  section.titleslide h1 { margin-top: 200px; }
  h1.title { margin-top: 150px; }
  h1 { font-size: 180%; }
  h2 { font-size: 120%; }
  h3 { font-size: 100%; }
  q { quotes: "“" "”" "‘" "’"; }
  blockquote, q {
    display: block;
    width: 90%;
    height: 100%;
    background-color: black;
    color: white;
    padding: 50px;
  }

  /* Figures are displayed full-page, with the caption on
     top of the image/video */
  figure {
    background-color: black;
    text-align: center;
  }
  img {
    max-width: 100%;
  }
  figcaption {
    margin: 70px;
  }
  pre {
    max-width: 100%;
    max-height: 380px;
    overflow: auto;
  }
  footer {
    position: absolute;
    bottom: 0;
    width: 100%;
    padding: 40px;
    text-align: right;
    background-color: #F3F4F8;
    border-top: 1px solid #CCC;
  }

  /* Transition effect */
  /* Feel free to change the transition effect for original
     animations. See here:
     https://developer.mozilla.org/en/CSS/CSS_transitions
     How to use CSS3 Transitions: */
  section {
      -moz-transition: left 400ms linear 0s;
      -webkit-transition: left 400ms linear 0s;
      -ms-transition: left 400ms linear 0s;
      transition: left 400ms linear 0s;
  }

  /* Before */
  section { left: -150%; }
  /* Now */
  section[aria-selected] { left: 0; }
  /* After */
  section[aria-selected] ~ section { left: +150%; }

  /* Incremental elements */

  /* By default, visible */
  .incremental > * { opacity: 1; }

  /* The current item */
  .incremental > *[aria-selected] { color: red; opacity: 1; }

  /* The items to-be-selected */
  .incremental > *[aria-selected] ~ * { opacity: 0.2; }
</style>
</head>
<body>
<section>
  <h1 class="title">New Tools for Reproducible Research with R</h1>
  <h2 class="author">JJ Allaire and Yihui Xie</h2>
  <h3 class="date">2012/06/14</h3>
</section>
<section class="slide level1" id="reproducible-research-with-r">
<h1 id="reproducible-research-with-r">Reproducible Research with R</h1>
<ul class="incremental">
<li><p>Single document containing analysis, code, and results</p></li>
<li><p>Sweave (included in R)</p>
<ul class="incremental">
<li>Created by Friedrich Leisch in 2002</li>
<li>Enables embedding R code into LaTeX documents</li>
</ul></li>
<li><p>New tools</p>
<ul class="incremental">
<li>Add powerful new capabilities to Sweave</li>
<li>Make authoring easier and more productive</li>
<li>Support publishing to the web</li>
</ul></li>
</ul>
</section>
<section class="slide level1" id="why-reproducible-research">
<h1 id="why-reproducible-research">Why Reproducible Research?</h1>
<ul class="incremental">
<li><p>Automatically regenerate documents when code, data, or assumptions change.</p></li>
<li><p>Eliminate transposition errors that occur when copying results into documents.</p></li>
<li><p>Preserve contextual narrative about why analysis was performed in a certain fashion.</p></li>
<li><p>Documentation for the analytic and computational processes from which conclusions are drawn.</p></li>
</ul>
</section>
<section class="slide level1" id="prime-directive-trustworthy-software">
<h1 id="prime-directive-trustworthy-software">Prime Directive: Trustworthy Software</h1>
<p><em>Those who receive the results of modern data analysis have limited opportunity to verify the results by direct observation. Users of the analysis have no option but to trust the analysis, and by extension the software that produced it.</em></p>
<p><em>This places an obligation on all creators of software to program in such a way that the computations can be understood and trusted. This obligation I label the <strong>Prime Directive</strong>.</em></p>
<br/>
<p><strong>Chambers, Software for Data Analysis: Programming with R</strong></p>
</section>
<section class="slide level1" id="new-tools">
<h1 id="new-tools">New Tools</h1>
<ul class="incremental">
<li>RStudio
<ul class="incremental">
<li>Productivity tools for Sweave / LaTeX</li>
</ul></li>
<li>knitr
<ul class="incremental">
<li>Many enhancements to Sweave</li>
<li>Extensible design for new capabilities and formats</li>
</ul></li>
<li>R Markdown
<ul class="incremental">
<li>Reproducible research for the web</li>
<li>Integerated support in RStudio and knitr</li>
</ul></li>
</ul>
</section>
<section class="slide level1" id="productivity-tools-for-sweave-latex">
<h1 id="productivity-tools-for-sweave-latex">Productivity Tools for Sweave / LaTeX</h1>
<ul class="incremental">
<li><p>Multi-mode editor (R and TeX aware)</p>
<ul class="incremental">
<li>Line by line R code execution</li>
<li>TeX formatting and spell checking</li>
</ul></li>
<li><p>One-click Compile PDF</p></li>
<li><p>Two-way sync between source and PDF (SyncTeX)</p></li>
<li><p>TeX error log parsing and navigation</p></li>
<li><p>Chunk navigation, execution, and code-completion</p></li>
</ul>
</section>
<section class="slide level1" id="r-markdown">
<h1 id="r-markdown">R Markdown</h1>
<ul class="incremental">
<li>What is Markdown?
<ul class="incremental">
<li>Easy to write plain text format for web authoring</li>
<li>Allows arbitrary HTML for complex formatting</li>
</ul></li>
<li>What is R Markdown?
<ul class="incremental">
<li>Standard markdown parser (Sundown)</li>
<li>Execution of R code chunks</li>
<li>MathJax extensions for LaTeX and MathML equations</li>
<li><a href="http://www.rstudio.org/docs/r_markdown">http://www.rstudio.org/docs/r_markdown</a></li>
</ul></li>
</ul>
</section>
<section class="slide level1" id="the-markdown-package">
<h1 id="the-markdown-package">The markdown Package</h1>
<p>This code produces an identical result to Knit HTML in RStudio (with no run-time dependency on RStudio):</p>
<pre class="sourceCode r"><code class="sourceCode r">   <span class="kw">knit</span>(<span class="st">&quot;foo.Rmd&quot;</span>)
   <span class="kw">markdownToHTML</span>(<span class="st">&quot;foo.md&quot;</span>)
   <span class="kw">browseURL</span>(<span class="st">&quot;foo.html&quot;</span>)   </code></pre>
<p>Enables use of R Markdown with any editor or IDE</p>
</section>
<section class="slide level1" id="distributing-r-markdown-documents">
<h1 id="distributing-r-markdown-documents">Distributing R Markdown Documents</h1>
<ul class="incremental">
<li>Standalone HTML files
<ul class="incremental">
<li>Embedded images (Base64 encoded)</li>
<li>Send as email attachment</li>
<li>Easy deployment to web server or Dropbox</li>
</ul></li>
<li>Use the <code>markdown</code> package for custom publishing
<ul class="incremental">
<li>Many blogs and wikis accept markdown input</li>
<li>Scheduled batch generation of reports on a server</li>
</ul></li>
<li>New services for publishing data analysis</li>
</ul>
</section>
<section class="slide level1" id="the-knitr-package">
<h1 id="the-knitr-package">The knitr Package</h1>
<ul class="incremental">
<li><p>Next-generation re-implementation of Sweave</p></li>
<li><p>Adds many features to Sweave including caching, syntax highlighting, code externalization, and new graphics capabilities</p></li>
<li><p>Very extensible design</p></li>
<li><p>Supports publishing to the web (R Markdown and R HTML)</p></li>
</ul>
</section>
<section class="slide level1" id="motivation-as-a-student-and-ta">
<h1 id="motivation-as-a-student-and-ta">Motivation (as a student and TA)</h1>
<p>I do homework, I grade homework, and I saw this:</p>
<figure>
<img src="http://i.imgur.com/ce1BT.png"><figcaption></figcaption>
</figure>
</section>
<section class="slide level1" id="principle-1-beautiful-output-by-default">
<h1 id="principle-1-beautiful-output-by-default">Principle 1: Beautiful output by default</h1>
<ul class="incremental">
<li>code highlighting (package <strong>highlight</strong>)
<ul class="incremental">
<li>carefully designed default themes</li>
<li>hundreds of themes</li>
</ul></li>
<li>reformat code for lazy users (package <strong>formatR</strong>)</li>
<li>plain text?</li>
</ul>
</section>
<section class="slide level1" id="code-highlighting">
<h1 id="code-highlighting">Code highlighting</h1>
<figure>
<img src="http://i.imgur.com/Tk0OF.png"><figcaption></figcaption>
</figure>
</section>
<section class="slide level1" id="code-reformatting">
<h1 id="code-reformatting">Code reformatting</h1>
<pre class="sourceCode r"><code class="sourceCode r">## option tidy=FALSE
for(k in <span class="dv">1</span>:<span class="dv">10</span>){j=<span class="kw">cos</span>(<span class="kw">sin</span>(k)*k^<span class="dv">2</span>)+<span class="dv">3</span>;<span class="kw">print</span>(j<span class="dv">-5</span>)}</code></pre>
<p>Same code, reformatted:</p>
<pre class="sourceCode r"><code class="sourceCode r">## option tidy=TRUE
for (k in <span class="dv">1</span>:<span class="dv">10</span>) {
  j = <span class="kw">cos</span>(<span class="kw">sin</span>(k) * k^<span class="dv">2</span>) + <span class="dv">3</span>
  <span class="kw">print</span>(j - <span class="dv">5</span>)
}</code></pre>
</section>
<section class="slide level1" id="principle-2-what-you-imagined-is-what-you-get">
<h1 id="principle-2-what-you-imagined-is-what-you-get">Principle 2: What you imagined is what you get</h1>
<ul class="incremental">
<li>running <strong>knitr</strong> gives you whatever you see in a normal R session</li>
<li><code>qplot(carat, price, data = diamonds)</code> just works; no need <code>print()</code> or <code>fig=TRUE</code></li>
<li>if your code produces two plots, you get two in the output</li>
<li>what if you have 50 plots? (demo)</li>
</ul>
</section>
<section class="slide level1" id="principle-3-focus-on-r-programming">
<h1 id="principle-3-focus-on-r-programming">Principle 3: Focus on R programming</h1>
<figure>
<img src="http://i.imgur.com/jrwbX.jpg"><figcaption></figcaption>
</figure>
</section>
<section class="slide level1" id="principle-4-be-sustainable">
<h1 id="principle-4-be-sustainable">Principle 4: Be sustainable</h1>
<p>Compare</p>
<pre class="sourceCode r"><code class="sourceCode r">&gt; (<span class="dt">x =</span> <span class="dv">0</span>)</code></pre>
<pre><code>[1] 0</code></pre>
<pre class="sourceCode r"><code class="sourceCode r">&gt; x = x + <span class="dv">1</span></code></pre>
<p>to (default):</p>
<pre class="sourceCode r"><code class="sourceCode r">(<span class="dt">x =</span> <span class="dv">0</span>)</code></pre>
<pre><code>## [1] 0</code></pre>
<pre class="sourceCode r"><code class="sourceCode r">x = x + <span class="dv">1</span></code></pre>
<p>You do not appreciate this unless you have been a homework grader.</p>
</section>
<section class="slide level1" id="principle-5-i-write-the-core-you-can-define-the-decoration">
<h1 id="principle-5-i-write-the-core-you-can-define-the-decoration">Principle 5: I write the core, you can define the decoration</h1>
<ul class="incremental">
<li>I parse/evaluate the code and give you the raw results, then you have control of everything</li>
<li>for example
<ul class="incremental">
<li>source code <code>1 + 1</code></li>
<li>output <code>[1] 2</code></li>
<li><em><code>\begin{verbatim}</code></em> <code>[1] 2</code> <em><code>\end{verbatim}</code></em></li>
<li>or <em><code>&lt;div class=&quot;output&quot;&gt;</code></em> <code>[1] 2</code> <em><code>&lt;/div&gt;</code></em></li>
<li>or <code>```[1] 2```</code></li>
</ul></li>
</ul>
</section>
<section class="slide level1" id="output-hooks">
<h1 id="output-hooks">Output hooks</h1>
<p>You can control how the source code, normal output, warnings, messages, errors and plots are written in the output document.</p>
<pre class="sourceCode r"><code class="sourceCode r">knit_hooks$<span class="kw">set</span>(<span class="dt">source =</span> function(x, options) {
    <span class="kw">paste</span>(<span class="st">&quot;</span><span class="ch">\\</span><span class="st">begin{DearSource}&quot;</span>, x, 
          <span class="st">&quot;</span><span class="ch">\\</span><span class="st">end{DearSource}&quot;</span>, <span class="dt">sep =</span> <span class="st">&quot;&quot;</span>)
})</code></pre>
<p>LaTeX, HTML, Markdown and reStructuredText have been supported, and it is straightforward to support other formats.</p>
</section>
<section class="slide level1" id="principle-6-all-your-base-are-belong-to-us">
<h1 id="principle-6-all-your-base-are-belong-to-us">Principle 6: All your base are belong to us</h1>
<ul class="incremental">
<li>the <code>tikz()</code> device supported by <strong>pgfSweave</strong></li>
<li>cache in <strong>cacheSweave</strong></li>
<li>automatic detection of chunk dependencies in <strong>weaver</strong></li>
<li>animations in my <strong>animation</strong> package</li>
<li><strong>knitr</strong> ≈ Sweave + cacheSweave + pgfSweave + weaver + <code>animation::saveLatex</code> + <code>R2HTML::RweaveHTML</code> + <code>highlight::HighlightWeaveLatex</code> + 0.2 * brew + 0.1 * SweaveListingUtils + more</li>
<li>without copying 700 lines of code</li>
</ul>
</section>
<section class="slide level1" id="principle-7-do-not-scare-beginners">
<h1 id="principle-7-do-not-scare-beginners">Principle 7: Do not scare beginners</h1>
<ul class="incremental">
<li>you get reasonable output even if you do not set any options; just <code>knit()</code> it (convention over configuration)</li>
<li>if you only have an R script, you can still do a report: <code>stitch()</code> or <code>spin()</code></li>
<li>if clicking a button works, click it
<ul class="incremental">
<li>RStudio</li>
<li>LyX (demo)</li>
</ul></li>
</ul>
</section>
<section class="slide level1" id="principle-8-open-source-is-open">
<h1 id="principle-8-open-source-is-open">Principle 8: Open source is open</h1>
<p>In theory you can use any language with <strong>knitr</strong>, e.g.</p>
<pre><code>&lt;&lt;test-python, engine=&#39;python&#39;&gt;&gt;=
x = &#39;hello, python world!&#39;
print x
print x.split(&#39; &#39;)
@</code></pre>
<p>Contributions needed!</p>
</section>
<section class="slide level1" id="principle-9-literate-programming-is-programming">
<h1 id="principle-9-literate-programming-is-programming">Principle 9: Literate programming is programming</h1>
<ul class="incremental">
<li>we can go beyond the model of <code>Code + Documentation</code></li>
<li>a LP document can be programmable</li>
</ul>
</section>
<section class="slide level1" id="programmable-reports-example-1">
<h1 id="programmable-reports-example-1">Programmable reports: Example 1</h1>
<pre><code>&lt;&lt;setup&gt;&gt;=
library(gridExtra)
g = tableGrob(head(iris, 4))
@

&lt;&lt;draw-table, fig.width=convertWidth(grobWidth(g), &quot;in&quot;, value=TRUE), fig.height=convertHeight(grobHeight(g), &quot;in&quot;, value=TRUE), dev=&#39;png&#39;, dpi=150&gt;&gt;=
grid.draw(g)
@</code></pre>
</section>
<section class="slide level1" id="programmable-reports-example-2">
<h1 id="programmable-reports-example-2">Programmable reports: Example 2</h1>
<p>Chunk hooks are functions associated with code chunks.</p>
<pre class="sourceCode r"><code class="sourceCode r">knit_hooks$<span class="kw">set</span>(<span class="dt">lord =</span> function(before, options, envir) {
  <span class="kw">library</span>(twitteR)
  <span class="co"># Authentication with OAuth here, then</span>
  if (!before) {
    msg = <span class="kw">paste</span>(<span class="st">&#39;I have finished the chunk&#39;</span>,
                options$label, <span class="st">&#39;, my Lord!&#39;</span>)
    <span class="kw">tweet</span>(msg)
  }
})
<span class="co"># enable the chunk hook</span>
opts_chunk$<span class="kw">set</span>(<span class="dt">lord =</span> <span class="ot">TRUE</span>)</code></pre>
</section>
<section class="slide level1" id="conclusions">
<h1 id="conclusions">Conclusions</h1>
<ul class="incremental">
<li>make reproducible research enjoyable first (new tools to hide gory details)</li>
<li>all people do homework assignments before they do research, so make your homework reproducible first</li>
<li>build extensible tools to satisfy both beginners and advanced users</li>
<li><strong>knitr</strong> allows any input languages and any output formats</li>
<li>reproducible blogging, exams/solutions, books, web tutorials, …</li>
<li>from reproducible reports to reproducible research</li>
</ul>
</section>
<section class="slide level1" id="in-code-we-trust">
<h1 id="in-code-we-trust">IN CODE WE TRUST</h1>
<p>Questions and comments?</p>
<ul class="incremental">
<li>RStudio: <a href="http://www.rstudio.org"><code class="url">http://www.rstudio.org</code></a></li>
<li>knitr: <a href="http://yihui.name/knitr/"><code class="url">http://yihui.name/knitr/</code></a></li>
</ul>
</section>
<!-- {{{{ dzslides core
#
#
#     __  __  __       .  __   ___  __
#    |  \  / /__` |    | |  \ |__  /__`
#    |__/ /_ .__/ |___ | |__/ |___ .__/ core :€
#
#
# The following block of code is not supposed to be edited.
# But if you want to change the behavior of these slides,
# feel free to hack it!
#
-->

<!-- Default Style -->
<style>
  * { margin: 0; padding: 0; }
  details { display: none; }
  body {
    width: 800px; height: 600px;
    margin-left: -400px; margin-top: -300px;
    position: absolute; top: 50%; left: 50%;
    overflow: hidden;
  }
  section {
    position: absolute;
    pointer-events: none;
    width: 100%; height: 100%;
  }
  section[aria-selected] { pointer-events: auto; }
  html { overflow: hidden; }
  body { display: none; }
  body.loaded { display: block; }
  .incremental {visibility: hidden; }
  .incremental[active] {visibility: visible; }
</style>

<script>
  var Dz = {
    remoteWindows: [],
    idx: -1,
    step: 0,
    slides: null,
    params: {
      autoplay: "1"
    }
  };

  Dz.init = function() {
    document.body.className = "loaded";
    this.slides = $$("body > section");
    this.setupParams();
    this.onhashchange();
    this.setupTouchEvents();
    this.onresize();
  }
  
  Dz.setupParams = function() {
    var p = window.location.search.substr(1).split('&');
    p.forEach(function(e, i, a) {
      var keyVal = e.split('=');
      Dz.params[keyVal[0]] = decodeURIComponent(keyVal[1]);
    });
  }

  Dz.onkeydown = function(aEvent) {
    // Don't intercept keyboard shortcuts
    if (aEvent.altKey
      || aEvent.ctrlKey
      || aEvent.metaKey
      || aEvent.shiftKey) {
      return;
    }
    if ( aEvent.keyCode == 37 // left arrow
      || aEvent.keyCode == 38 // up arrow
      || aEvent.keyCode == 33 // page up
    ) {
      aEvent.preventDefault();
      this.back();
    }
    if ( aEvent.keyCode == 39 // right arrow
      || aEvent.keyCode == 40 // down arrow
      || aEvent.keyCode == 34 // page down
    ) {
      aEvent.preventDefault();
      this.forward();
    }
    if (aEvent.keyCode == 35) { // end
      aEvent.preventDefault();
      this.goEnd();
    }
    if (aEvent.keyCode == 36) { // home
      aEvent.preventDefault();
      this.goStart();
    }
    if (aEvent.keyCode == 32) { // space
      aEvent.preventDefault();
      this.toggleContent();
    }
  }

  /* Touch Events */

  Dz.setupTouchEvents = function() {
    var orgX, newX;
    var tracking = false;

    var db = document.body;
    db.addEventListener("touchstart", start.bind(this), false);
    db.addEventListener("touchmove", move.bind(this), false);

    function start(aEvent) {
      aEvent.preventDefault();
      tracking = true;
      orgX = aEvent.changedTouches[0].pageX;
    }

    function move(aEvent) {
      if (!tracking) return;
      newX = aEvent.changedTouches[0].pageX;
      if (orgX - newX > 100) {
        tracking = false;
        this.forward();
      } else {
        if (orgX - newX < -100) {
          tracking = false;
          this.back();
        }
      }
    }
  }

  /* Adapt the size of the slides to the window */

  Dz.onresize = function() {
    var db = document.body;
    var sx = db.clientWidth / window.innerWidth;
    var sy = db.clientHeight / window.innerHeight;
    var transform = "scale(" + (1/Math.max(sx, sy)) + ")";

    db.style.MozTransform = transform;
    db.style.WebkitTransform = transform;
    db.style.OTransform = transform;
    db.style.msTransform = transform;
    db.style.transform = transform;
  }


  Dz.getDetails = function(aIdx) {
    var s = $("section:nth-of-type(" + aIdx + ")");
    var d = s.$("details");
    return d ? d.innerHTML : "";
  }

  Dz.onmessage = function(aEvent) {
    var argv = aEvent.data.split(" "), argc = argv.length;
    argv.forEach(function(e, i, a) { a[i] = decodeURIComponent(e) });
    var win = aEvent.source;
    if (argv[0] === "REGISTER" && argc === 1) {
      this.remoteWindows.push(win);
      this.postMsg(win, "REGISTERED", document.title, this.slides.length);
      this.postMsg(win, "CURSOR", this.idx + "." + this.step);
      return;
    }
    if (argv[0] === "BACK" && argc === 1)
      this.back();
    if (argv[0] === "FORWARD" && argc === 1)
      this.forward();
    if (argv[0] === "START" && argc === 1)
      this.goStart();
    if (argv[0] === "END" && argc === 1)
      this.goEnd();
    if (argv[0] === "TOGGLE_CONTENT" && argc === 1)
      this.toggleContent();
    if (argv[0] === "SET_CURSOR" && argc === 2)
      window.location.hash = "#" + argv[1];
    if (argv[0] === "GET_CURSOR" && argc === 1)
      this.postMsg(win, "CURSOR", this.idx + "." + this.step);
    if (argv[0] === "GET_NOTES" && argc === 1)
      this.postMsg(win, "NOTES", this.getDetails(this.idx));
  }

  Dz.toggleContent = function() {
    // If a Video is present in this new slide, play it.
    // If a Video is present in the previous slide, stop it.
    var s = $("section[aria-selected]");
    if (s) {
      var video = s.$("video");
      if (video) {
        if (video.ended || video.paused) {
          video.play();
        } else {
          video.pause();
        }
      }
    }
  }

  Dz.setCursor = function(aIdx, aStep) {
    // If the user change the slide number in the URL bar, jump
    // to this slide.
    aStep = (aStep != 0 && typeof aStep !== "undefined") ? "." + aStep : ".0";
    window.location.hash = "#" + aIdx + aStep;
  }

  Dz.onhashchange = function() {
    var cursor = window.location.hash.split("#"),
        newidx = 1,
        newstep = 0;
    if (cursor.length == 2) {
      newidx = ~~cursor[1].split(".")[0];
      newstep = ~~cursor[1].split(".")[1];
      if (newstep > Dz.slides[newidx - 1].$$('.incremental > *').length) {
        newstep = 0;
        newidx++;
      }
    }
    if (newidx != this.idx) {
      this.setSlide(newidx);
    }
    if (newstep != this.step) {
      this.setIncremental(newstep);
    }
    for (var i = 0; i < this.remoteWindows.length; i++) {
      this.postMsg(this.remoteWindows[i], "CURSOR", this.idx + "." + this.step);
    }
  }

  Dz.back = function() {
    if (this.idx == 1 && this.step == 0) {
      return;
    }
    if (this.step == 0) {
      this.setCursor(this.idx - 1,
                     this.slides[this.idx - 2].$$('.incremental > *').length);
    } else {
      this.setCursor(this.idx, this.step - 1);
    }
  }

  Dz.forward = function() {
    if (this.idx >= this.slides.length &&
        this.step >= this.slides[this.idx - 1].$$('.incremental > *').length) {
        return;
    }
    if (this.step >= this.slides[this.idx - 1].$$('.incremental > *').length) {
      this.setCursor(this.idx + 1, 0);
    } else {
      this.setCursor(this.idx, this.step + 1);
    }
  }

  Dz.goStart = function() {
    this.setCursor(1, 0);
  }

  Dz.goEnd = function() {
    var lastIdx = this.slides.length;
    var lastStep = this.slides[lastIdx - 1].$$('.incremental > *').length;
    this.setCursor(lastIdx, lastStep);
  }

  Dz.setSlide = function(aIdx) {
    this.idx = aIdx;
    var old = $("section[aria-selected]");
    var next = $("section:nth-of-type("+ this.idx +")");
    if (old) {
      old.removeAttribute("aria-selected");
      var video = old.$("video");
      if (video) {
        video.pause();
      }
    }
    if (next) {
      next.setAttribute("aria-selected", "true");
      var video = next.$("video");
      if (video && !!+this.params.autoplay) {
        video.play();
      }
    } else {
      // That should not happen
      this.idx = -1;
      // console.warn("Slide doesn't exist.");
    }
  }

  Dz.setIncremental = function(aStep) {
    this.step = aStep;
    var old = this.slides[this.idx - 1].$('.incremental > *[aria-selected]');
    if (old) {
      old.removeAttribute('aria-selected');
    }
    var incrementals = this.slides[this.idx - 1].$$('.incremental');
    if (this.step <= 0) {
      incrementals.forEach(function(aNode) {
        aNode.removeAttribute('active');
      });
      return;
    }
    var next = this.slides[this.idx - 1].$$('.incremental > *')[this.step - 1];
    if (next) {
      next.setAttribute('aria-selected', true);
      next.parentNode.setAttribute('active', true);
      var found = false;
      incrementals.forEach(function(aNode) {
        if (aNode != next.parentNode)
          if (found)
            aNode.removeAttribute('active');
          else
            aNode.setAttribute('active', true);
        else
          found = true;
      });
    } else {
      setCursor(this.idx, 0);
    }
    return next;
  }
  
  Dz.postMsg = function(aWin, aMsg) { // [arg0, [arg1...]]
    aMsg = [aMsg];
    for (var i = 2; i < arguments.length; i++)
      aMsg.push(encodeURIComponent(arguments[i]));
    aWin.postMessage(aMsg.join(" "), "*");
  }

  window.onload = Dz.init.bind(Dz);
  window.onkeydown = Dz.onkeydown.bind(Dz);
  window.onresize = Dz.onresize.bind(Dz);
  window.onhashchange = Dz.onhashchange.bind(Dz);
  window.onmessage = Dz.onmessage.bind(Dz);
</script>


<script> // Helpers
  if (!Function.prototype.bind) {
    Function.prototype.bind = function (oThis) {

      // closest thing possible to the ECMAScript 5 internal IsCallable
      // function 
      if (typeof this !== "function")
      throw new TypeError(
        "Function.prototype.bind - what is trying to be fBound is not callable"
      );

      var aArgs = Array.prototype.slice.call(arguments, 1),
          fToBind = this,
          fNOP = function () {},
          fBound = function () {
            return fToBind.apply( this instanceof fNOP ? this : oThis || window,
                   aArgs.concat(Array.prototype.slice.call(arguments)));
          };

      fNOP.prototype = this.prototype;
      fBound.prototype = new fNOP();

      return fBound;
    };
  }

  var $ = (HTMLElement.prototype.$ = function(aQuery) {
    return this.querySelector(aQuery);
  }).bind(document);

  var $$ = (HTMLElement.prototype.$$ = function(aQuery) {
    return this.querySelectorAll(aQuery);
  }).bind(document);

  NodeList.prototype.forEach = function(fun) {
    if (typeof fun !== "function") throw new TypeError();
    for (var i = 0; i < this.length; i++) {
      fun.call(this, this[i]);
    }
  }

</script>
<!-- vim: set fdm=marker: }}} -->
</body>
</html>
